<template>
  <Model :="$attrs">
    <n-form
      size="small"
      class="w100"
    >
      <n-grid
        :cols="24"
        :x-gap="16"
      >
        <n-form-item-gi
          v-for="item in showConfig"
          :span="item.span || 12"
          :label="item.label"
          :key="item.key"
        >
          <n-select
            v-if="item.type === 'select'"
            :options="item.options"
            v-model:value="form[item.key]"
          />
          <n-select
            v-else-if="item.type === 'multiple-select'"
            multiple
            :options="item.options"
            v-model:value="form[item.key]"
          />
          <n-tree-select
            clearable
            v-else-if="item.type === 'tree-select'"
            :options="item.options"
            v-model:value="form[item.key]"
            :default-value="item.defaultValue"
          />
          <n-tree
            v-else-if="item.type === 'tree'"
            :data="item.options"
            v-model:checked-keys="form[item.key]"
            :show-line="false"
            default-expand-all
            checkable
            expand-on-click
            selectable
          />
          <n-input
            v-else-if="item.type === 'input'"
            v-model:value="form[item.key]"
          />
          <n-input-number
            v-else-if="item.type === 'input-number'"
            v-model:value="form[item.key]"
            style="width: 100%"
          />
          <n-radio-group
            v-else-if="item.type === 'radio'"
            v-model:value="form[item.key]"
          >
            <n-flex>
              <n-radio
                v-for="i in item.options"
                :key="i.value"
                :value="i.value"
                >{{ i.label }}</n-radio
              >
            </n-flex>
          </n-radio-group>
        </n-form-item-gi>
      </n-grid>
    </n-form>
  </Model>
</template>

<script lang="ts" setup>
  import Model from '../Modal/index.vue'
  import type { SelectOption, TreeOption } from 'naive-ui'
  import type { Ref, VNode, ComputedRef } from 'vue'

  interface FormConfig {
    key: string
    label: string
    span?: number
    show: boolean | ComputedRef<boolean>
  }
  interface FormInput extends FormConfig {
    type: 'input'
  }
  interface FormInputNumber extends FormConfig {
    type: 'input-number'
  }
  interface FormSelect extends FormConfig {
    type: 'select' | 'radio' | 'multiple-select'
    options: SelectOption[]
  }

  interface FormTreeSelect extends FormConfig {
    type: 'tree-select' | 'tree'
    defaultValue?: string | number
    options: TreeOption[] | Ref<TreeOption[]>
  }

  interface FormSlot extends FormConfig {
    type: 'slot'
    slot: VNode | VNode[]
  }

  export type ModalFormConfig = FormInput | FormSelect | FormTreeSelect | FormSlot | FormInputNumber
  const props = defineProps<{
    config: ModalFormConfig[]
  }>()

  const showConfig = computed(() => props.config.filter(item => item.show))

  const form = defineModel<Record<string, any>>('form', { default: {}, required: true })
</script>

<style scoped lang="scss"></style>
